import { ActivatedRouteSnapshot, BaseRouteReuseStrategy, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router';


// shouldReuseRoute-> retrieve -> shouldDetach (离开当前页时确定是否可复用)  
//                                      |                               
//                         |-- false -- | -- true--> store                              
//                         |                          |
//                       shouldAttach <---------------|                                  
//                              |
//               结束<-- false--|--- true -->  store --> retrieve --> 结束
//
// 路由替换是直接替换 app-root 节点，某些组件就会被 destroy，这时 shouldDetech, store 就会被调用, 用于缓存这些已经渲染完成即将被丢弃的组件
//   有组件被丢弃自然有组件需要进来替补, 而这时 shouldAttach,retrieve 就会被调用, 用来调出缓存的组件

export class CustomReuseStrategy extends BaseRouteReuseStrategy {

    static cacheRouters = new Map<string, DetachedRouteHandle>();

    public static deleteRouteCache(url): void {
        if (CustomReuseStrategy.cacheRouters.has(url)) {
            const handle: any = CustomReuseStrategy.cacheRouters.get(url);
            try {
                handle.componentRef.destory();
            } catch (e) { }
            CustomReuseStrategy.cacheRouters.delete(url);
        }
    }

    public static deleteAllRouteCache(): void {
        CustomReuseStrategy.cacheRouters.forEach((handle: any, key) => {
            CustomReuseStrategy.deleteRouteCache(key);
        });
    }


    /**
     * 确定是否复用路由
     */
    override shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        //console.info('future:');
        //console.info(future);
        //console.info('curr:');
        //console.info(curr);
        return future.routeConfig === curr.routeConfig &&
            JSON.stringify(future.params) === JSON.stringify(curr.params);
    }

    /** try get store routes for later re-use. */
    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
        const url = this.getFullRouteURL(route);
        if (route.data.keep && CustomReuseStrategy.cacheRouters.has(url)) {
            return CustomReuseStrategy.cacheRouters.get(url);
        } else {
            return null;
        }
    }

    /**
     * Whether the given route should detach for later reuse.
     * */
    shouldDetach(route: ActivatedRouteSnapshot): boolean {
        return Boolean(route.data.keep);
    }

    /**
     * store the route for later re-use.
    */
    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle | null): void {
        const url = this.getFullRouteURL(route);
        CustomReuseStrategy.cacheRouters.set(url, handle);
    }

    /** Returns `false`, meaning the route (and its subtree) is never reattached */
    shouldAttach(route: ActivatedRouteSnapshot): boolean {
        const url = this.getFullRouteURL(route);
        return Boolean(route.data.keep) && CustomReuseStrategy.cacheRouters.has(url);
    }


    // 获取当前路由url
    private getFullRouteURL(route: ActivatedRouteSnapshot): string {
        const { pathFromRoot } = route;
        let fullRouteUrlPath: string[] = [];
        pathFromRoot.forEach((item: ActivatedRouteSnapshot) => {
            fullRouteUrlPath = fullRouteUrlPath.concat(this.getRouteUrlPath(item));
        });
        return `/${fullRouteUrlPath.join('/')}`;

    }
    private getRouteUrlPath(route: ActivatedRouteSnapshot) {
        return route.url.map(urlSegment => urlSegment.path);
    }

}
